package com.xtaller.sdboot.core.base;

import com.alibaba.fastjson.JSONObject;
import com.xtaller.sdboot.core.R;
import com.xtaller.sdboot.core.Status;
import com.xtaller.sdboot.core.helper.BeanHelper;
import com.xtaller.sdboot.core.helper.ContextHelper;
import com.xtaller.sdboot.utils.helper.*;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.var;

import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;

/**
 * @author : Taller
 * @date : 2020/1/15 00:01
 * @Description :
 */
public class RestController<E extends BaseEntity> extends OriginalController {

    private Class<E> entityClass;
    private BaseService baseService;

    protected Object get(Serializable id, HttpServletRequest request) throws Exception {
        if (id == null) {
            return R.error(Status.FAIL_INVALID_PARAM, "请选择需要操作的数据Id");
        }
        var model = getService().get(id);
        if(model == null){
            return R.error(Status.FAIL_NOT_FOUND, "数据id异常");
        }
        var validateResult = this.beforeGet(id, request);
        if (validateResult != null) {
            // 返回json
            return R.error(Status.FAIL_OPERATION, validateResult);
        }

        return R.ok(this.afterGet(JsonHelper.o2j(model)));
    }

    /***
     * 创建资源对象，用于子类重写的方法
     * @param entity
     * @return Json
     * @throws Exception
     */
    protected Object create(E entity, HttpServletRequest request) throws Exception {
        // 执行创建资源前的操作
        var beforeOpt = this.beforeCreate(entity);
        if (beforeOpt != null) {
            return R.error(Status.FAIL_OPERATION, beforeOpt);
        }
        // 执行保存操作
        boolean success = getService().create(entity);
        if (success) {
            // 执行创建成功后的操作
            var afterOpt = this.afterCreated(entity);
            if (afterOpt != null) {
                log.warn("部分操作成功，entity=" + entity.getClass().getSimpleName());
                return R.error(Status.WARN_PARTIAL_SUCCESS, afterOpt);
            }
            // 组装返回结果
            Map<String, Object> data = new HashMap<>(2);
            data.put("id", entity.getId());
            return R.ok(Status.OK, data);
        } else {
            log.warn("创建操作未成功，entity=" + entity.getClass().getSimpleName());
            // 组装返回结果
            return R.error(Status.FAIL_OPERATION);
        }
    }

    /***
     * 根据ID更新资源对象，用于字类重写的方法
     * @param entity
     * @return JsonResult
     * @throws Exception
     */
    protected Object update(Serializable id, E entity, HttpServletRequest request) throws Exception {
        if (id == null) {
            return R.error(Status.FAIL_INVALID_PARAM, "请选择需要操作的数据Id");
        }
        // 旧数据
        var oldData = (E) getService().get(id);
        if(oldData == null){
            return R.error(Status.FAIL_NOT_FOUND, "数据id异常");
        }
        entity.setId((String) id);
        // 执行更新资源前的操作
        var beforeOpt = this.beforeUpdate(entity);
        if (beforeOpt != null) {
            return R.error(Status.FAIL_OPERATION, beforeOpt);
        }
        // 执行保存操作
        boolean success = getService().update(entity);
        if (success) {
            // 执行更新成功后的操作
            var afterOPt = this.afterUpdated(oldData, entity);
            if (afterOPt != null) {
                return R.error(Status.WARN_PARTIAL_SUCCESS, afterOPt);
            }
            // 组装返回结果
            Map<String, Object> data = new HashMap<>(2);
            data.put("id", entity.getId());
            return R.ok(Status.OK, data);
        } else {
            log.warn("更新操作失败，{}:{}", entity.getClass().getSimpleName(), entity.getId());
            // 返回操作结果
            return R.error(Status.FAIL_OPERATION);
        }
    }

    /***
     * 根据id删除资源对象，绑定了URL的方法 用于字类重写的方法
     * @param id
     * @return
     * @throws Exception
     */
    protected Object delete(Serializable id, HttpServletRequest request) throws Exception {
        if (id == null) {
            return R.error(Status.FAIL_INVALID_PARAM, "请选择需要操作的数据Id");
        }
        var model = (E) getService().get(id);
        if(model == null){
            return R.error(Status.FAIL_NOT_FOUND, "数据id异常");
        }
        // 执行删除操作前
        String validateResult = beforeDelete(model);
        if (validateResult != null) {
            // 返回json
            return R.error(Status.FAIL_OPERATION, validateResult);
        }
        // 执行删除操作
        boolean success = getService().delete(id);
        if (success) {
            // 组装返回结果
            Map<String, Object> data = new HashMap<>(2);
            data.put("id", model.getId());
            // 执行成功后的操作
            this.afterDelete(model);
            return R.ok(Status.OK, data);
        } else {
            return R.error(Status.FAIL_OPERATION);
        }
    }

    /**
     * 获取符合查询条件的分页数据
     * @param
     * @return
     * @throws Exception
     */
    protected Object getPage(Map<String, Object> params) throws Exception {
        var validateResult = this.beforePage(params);
        if (validateResult != null) {
            // 返回json
            return R.error(Status.FAIL_OPERATION, validateResult);
        }
        // 分页
        var page = pageer(params);

        var p = new Page<E>(page.getCurrent(), page.getLimit());
        var qw = convertMap2Wrapper(params);

        // 返回结果
        var data = getService().pages(p, qw);
        var pageData = JsonHelper.create("code", 0)
                .put("data", data.getRecords())
                .put("current", Integer.parseInt(data.getCurrent() + ""))
                .put("pages", Integer.parseInt(data.getPages() + ""))
                .put("count", Integer.parseInt(data.getTotal() + ""))
                .put("size", Integer.parseInt(data.getSize() + ""))
                .put("code", 0)
                .put("msg", "读取成功");

        return this.afterPage(pageData);
    }
    /**
     * 将page<T>转成layui的table的数据格式
     * */
    public Function<Object, JSONObject> p2t = object -> {
        var tem = JsonHelper.o2j(object);
        var r = new JSONObject();
        r.put("code", 0);
        r.put("message", "读取成功");
        r.put("current", tem.getInteger("current") == null ? 1 : tem.getInteger("current"));
        r.put("size", tem.getInteger("size") == null ? 0 : tem.getInteger("size"));
        r.put("count", tem.getInteger("total") == null ? 0 : tem.getInteger("total"));
        r.put("pages", tem.getInteger("pages") == null ? 1 : tem.getInteger("pages"));

        r.put("data", tem.get("records") == null ? tem.get("result") : tem.get("records"));
        return r;
    };

    /**
     * 得到service
     * @return
     */
    protected BaseService getService() {
        Class<E> clazz = getEntityClass();
        return getService(clazz);
    }
    protected BaseService getService(Class<E> cls) {
        if(this.baseService == null){
            if(cls != null){
                this.baseService = ContextHelper.getBaseServiceByEntity(cls);
            }
            if(this.baseService == null){
                log.warn("Entity: {} 无对应的Service定义，请检查！", cls.getName());
            }
        }
        return this.baseService;
    }

    /**
     * 获取Entity的class
     * @return
     */
    protected Class<E> getEntityClass(){
        if(this.entityClass == null){
            this.entityClass = BeanHelper.getGenericityClass(this.getClass(), 0);
        }
        return this.entityClass;
    }

    /***
     * 根据id读取数据前
     * @param id
     * @return
     */
    protected String beforeGet(Serializable id, HttpServletRequest request) {
        return null;
    }

    /***
     * 根据id读取数据后
     * @param json
     * @return
     */
    protected JSONObject afterGet(JSONObject json) {
        return json;
    }

    /***
     * 创建前的相关处理
     * @param entity
     * @return
     */
    protected String beforeCreate(BaseEntity entity) throws Exception {
        return null;
    }

    /***
     * 创建成功后的相关处理
     * @param entity
     * @return
     */
    protected String afterCreated(BaseEntity entity) throws Exception {
        return null;
    }

    /***
     * 更新前的相关处理
     * @param entity
     * @return
     */
    protected String beforeUpdate(BaseEntity entity) throws Exception {
        if(entity == null){
            return "数据Id异常";
        }
        return null;
    }

    /***
     * 更新成功后的相关处理
     * @param oldEntity newEntity
     * @return
     */
    protected String afterUpdated(BaseEntity oldEntity, BaseEntity newEntity) throws Exception {
        return null;
    }

    /***
     * 分页数据前处理
     * @return
     */
    protected String beforePage(Map<String, Object> params) throws Exception {
        return null;
    }

    /***
     * 分页数据后处理
     * @param json
     * @return
     */
    protected JSONObject afterPage(JSONObject json) throws Exception {
        return json;
    }

    /***
     * 是否有删除权限，如不可删除返回错误提示信息，如 Status.FAIL_NO_PERMISSION.label()
     * @param entity
     * @return
     */
    protected String beforeDelete(BaseEntity entity) throws Exception {
        return null;
    }

    protected String afterDelete(BaseEntity entity) throws Exception {
        return null;
    }



}
